package com.clarte.common.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

@Repository("baseDao")
public class BaseDaoImpl<T, PK extends Serializable> implements BaseDao<T, PK> {
	private Class<T> entity;
	@Resource(name="hibernateTemplate")
	private HibernateTemplate hibernateTemplate;
	
	private EntityManager em;	
//	@PersistenceContext
	public void setEntityManager(EntityManager em) {
		this.em = em;
	}
	
	{
		try{
			entity = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		}catch(Exception e){}
	}
	public void save(T t){
		hibernateTemplate.save(t);
	}
	public void delete(PK... pk){
		for(PK i : pk){
			hibernateTemplate.delete(this.get(i));
		}
	}
	public void update(T t){
		hibernateTemplate.update(t);
	}
	public T get(PK pk){
		return (T)hibernateTemplate.get(entity, pk);
	}
	public List<T> findAll(){
		return hibernateTemplate.loadAll(entity);
	}
	public List<T> find(String hql,Object[] obj){
		return hibernateTemplate.find(hql, obj);
	}
	public List<T> find(DetachedCriteria criteria){
		return hibernateTemplate.findByCriteria(criteria);
	}
	public List<T> findByCriteria(DetachedCriteria criteria,int firstResult,int maxResults){
		return hibernateTemplate.findByCriteria(criteria, firstResult, maxResults);
	}
	public List<T> find(String hql,Object[] param,int firstResult,int maxResults){
		Query query = this.getQuery(hql, param);
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		return query.list();
	}
	public long getTotal(String hql){
		return (Long)hibernateTemplate.iterate(hql).next();
	}
	public long getTotal(String hql,Object[] obj){
		return (Long)hibernateTemplate.iterate(hql, obj).next();
	}
	public long getTotal(DetachedCriteria criteria){
		return (Integer)hibernateTemplate.findByCriteria(criteria).get(0);
	}
	public long getNextNum(){
		return (Long)hibernateTemplate.iterate("select max(e.id) from "+entity.getName()+" e").next() + 1;
	}
	public void executeUpdate(String hql,Object[] param){
		Query query = this.getQuery(hql, param);
		query.executeUpdate();
	}
	private Query getQuery(String hql,Object[] param){
		Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
		Query query = session.createQuery(hql);
		if(param != null){
			for(int i = 0; i < param.length; i++){
				query.setParameter(i, param[i]);
			}
		}
		return query;
	}
}
